﻿using Opc.Ua;
using Opc.Ua.Client;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Entity.ScadaBaseInfo;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.Service.OpcService;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SHRIS.MIS.Service.Device
{
    public class HoleDepthMeasure_02 : BasicDevice
    {
        private readonly IEnumerable<OpcDataSourceEntity> _opcDataSourceEntities;

        public HoleDepthMeasure_02(DeviceEntity deviceEntity,
            WorkshopCommunicationService workshopCommunicationService,
            IEnumerable<OpcDataSourceEntity> opcDataSourceEntities)
            : base(deviceEntity, workshopCommunicationService)
        {
            _opcDataSourceEntities = opcDataSourceEntities;
            CheckOutDataType();
        }


        private void CheckOutDataType()
        {
            //对所有OPC 数据类型进行校验，如果不对记入LOG

        }

        public override void InitalDevice()
        {
            //创建opc 订阅

            //找出该通道下的订阅数据，dataAction==4 为订阅
            var subscriptionDatas = _opcDataSourceEntities.Where(i => i.DataAction == 4);

            //找出订阅数据的服务器列表
            var serverIds = subscriptionDatas.Select(i => i.ServerId).Distinct().ToList();

            if (serverIds.Count() == 1)
            {
                _workshopCommunicationService.CreateOpcSubscription(subscriptionDatas, DataHandler);
            }


            //用deviceCode作为订阅组名字
            //var subscriptionName = _deviceEntity.DeviceCode;

        }

        private void DataHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                //Console.WriteLine(notification.Value.StatusCode.ToString());

                if (notification != null)
                {
                    Guid dataId = new Guid();
                    bool isId = Guid.TryParse(monitoredItem.DisplayName, out dataId);
                    if (isId && (!dataId.IsGuidNullOrEmpty()))
                    {
                        var dataSource = _opcDataSourceEntities.Where(i => i.Id == dataId).First();
                        switch (dataSource.DataName)
                        {
                            case "BypassStatus":
                                {
                                    BypassStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "EMO":
                                {
                                    EMO = (bool)notification.Value.Value;
                                    break;
                                }
                            case "Ready":
                                {
                                    Ready = (bool)notification.Value.Value;
                                    break;
                                }
                            case "End":
                                {
                                    End = (bool)notification.Value.Value;
                                    break;
                                }
                            case "HasWorkpiece":
                                {
                                    HasWorkpiece = (bool)notification.Value.Value;
                                    break;
                                }
                            case "RealCount":
                                {
                                    RealCount = (short)notification.Value.Value;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    WorkpieceSource = (short)notification.Value.Value;
                                    break;
                                }
                            case "CountSet":
                                {
                                    CountSet = (short)notification.Value.Value;
                                    break;
                                }
                            case "MaterialCode":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        MaterialCode = (string)notification.Value.Value;
                                    }

                                    break;
                                }
                            case "Depth":
                                {
                                    Depth = double.Parse(notification.Value.Value.ToString());
                                    break;
                                }
                            case "HoLength":
                                {
                                    HoLength = double.Parse(notification.Value.Value.ToString());
                                    break;
                                }
                            case "ValAct":
                                {
                                    ValAct = (bool)notification.Value.Value;
                                    break;
                                }
                            case "DMEquStaW":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    DMEquStaW = new BitArray(b);
                                    break;
                                }
                            case "DMEquProStaW":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    DMEquProStaW = new BitArray(b);
                                    break;
                                }
                            case "DMEquAlarmW_1":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    DMEquAlarmW_1 = new BitArray(b);
                                    break;
                                }
                            case "DMEquAlarmW_2":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    DMEquAlarmW_2 = new BitArray(b);
                                    break;
                                }
                            case "DMEquActProNo":
                                {
                                    DMEquActProNo = notification.Value.Value.ToString();
                                    break;
                                }
                            case "DMEquStartEquTime":
                                {
                                    DMEquStartEquTime = DateTimeOffset.Parse(notification.Value.Value.ToString());
                                    break;
                                }
                            case "DMEquRunningTime":
                                {
                                    DMEquRunningTime = double.Parse(notification.Value.Value.ToString());
                                    break;
                                }
                            default:
                                {
                                    break;
                                }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region 设备参数

        private BitArray dMEquStaW;
        /// <summary>
        /// 孔深测量设备状态字
        /// </summary>
        public BitArray DMEquStaW
        {
            get
            {
                return dMEquStaW;
            }
            set
            {
                BitArray previewVlaue = dMEquStaW;
                dMEquStaW = value;
                OnPropertyChanged("DMEquStaW", previewVlaue, dMEquStaW);
            }
        }

        private BitArray dMEquProStaW;
        /// <summary>
        /// 孔深测量程序状态字
        /// </summary>
        public BitArray DMEquProStaW
        {
            get
            {
                return dMEquProStaW;
            }
            set
            {
                BitArray previewVlaue = dMEquProStaW;
                dMEquProStaW = value;
                OnPropertyChanged("DMEquProStaW", previewVlaue, dMEquProStaW);
            }
        }

        private BitArray dMEquAlarmW_1;
        /// <summary>
        /// 孔深测量设备报警字1
        /// </summary>
        public BitArray DMEquAlarmW_1
        {
            get
            {
                return dMEquAlarmW_1;
            }
            set
            {
                BitArray previewVlaue = dMEquAlarmW_1;
                dMEquAlarmW_1 = value;
                OnPropertyChanged("DMEquAlarmW_1", previewVlaue, dMEquAlarmW_1);
            }
        }

        private BitArray dMEquAlarmW_2;
        /// <summary>
        /// 孔深测量设备报警字2
        /// </summary>
        public BitArray DMEquAlarmW_2
        {
            get
            {
                return dMEquAlarmW_2;
            }
            set
            {
                BitArray previewVlaue = dMEquAlarmW_2;
                dMEquAlarmW_2 = value;
                OnPropertyChanged("DMEquAlarmW_2", previewVlaue, dMEquAlarmW_2);
            }
        }

        private string dMEquActProNo;
        /// <summary>
        /// 孔深测量当前程序号
        /// </summary>
        public string DMEquActProNo
        {
            get
            {
                return dMEquActProNo;
            }
            set
            {
                string previewVlaue = dMEquActProNo;
                dMEquActProNo = value;
                OnPropertyChanged("DMEquActProNo", previewVlaue, dMEquActProNo);
            }
        }

        private DateTimeOffset dMEquStartEquTime;
        /// <summary>
        /// 孔深测量设备本次开机时刻
        /// </summary>
        public DateTimeOffset DMEquStartEquTime
        {
            get
            {
                return dMEquStartEquTime;
            }
            set
            {
                DateTimeOffset previewVlaue = dMEquStartEquTime;
                dMEquStartEquTime = value;
                OnPropertyChanged("DMEquStartEquTime", previewVlaue, dMEquStartEquTime);
            }
        }

        private double dMEquRunningTime;
        /// <summary>
        /// 孔深测量开机时间，永不清零（单位:小时）
        /// </summary>
        public double DMEquRunningTime
        {
            get
            {
                return dMEquRunningTime;
            }
            set
            {
                double previewVlaue = dMEquRunningTime;
                dMEquRunningTime = value;
                OnPropertyChanged("DMEquRunningTime", previewVlaue, dMEquRunningTime);
            }
        }

        private bool bypassStatus;
        /// <summary>
        /// 孔深测量Bypass
        /// </summary>
        public bool BypassStatus
        {
            get
            {
                return bypassStatus;
            }
            set
            {
                bool previewVlaue = bypassStatus;
                bypassStatus = value;
                OnPropertyChanged("BypassStatus", previewVlaue, bypassStatus);
            }
        }

        private bool eMO;
        /// <summary>
        /// 急停
        /// </summary>
        public bool EMO
        {
            get
            {
                return eMO;
            }
            set
            {
                bool previewVlaue = eMO;
                eMO = value;
                OnPropertyChanged("EMO", previewVlaue, eMO);
            }
        }

        private bool ready;
        /// <summary>
        /// 准备
        /// </summary>
        public bool Ready
        {
            get
            {
                return ready;
            }
            set
            {
                bool previewVlaue = ready;
                ready = value;
                OnPropertyChanged("Ready", previewVlaue, ready);
            }
        }

        private bool end;
        /// <summary>
        /// 结束
        /// </summary>
        public bool End
        {
            get
            {
                return end;
            }
            set
            {
                bool previewVlaue = end;
                end = value;
                OnPropertyChanged("End", previewVlaue, end);
            }
        }

        private bool hasWorkpiece;
        /// <summary>
        /// 有工件
        /// </summary>
        public bool HasWorkpiece
        {
            get
            {
                return hasWorkpiece;
            }
            set
            {
                bool previewVlaue = hasWorkpiece;
                hasWorkpiece = value;
                OnPropertyChanged("HasWorkpiece", previewVlaue, hasWorkpiece);
            }
        }

        private short realCount;
        /// <summary>
        /// 实际测量次数
        /// </summary>
        public short RealCount
        {
            get
            {
                return realCount;
            }
            set
            {
                short previewVlaue = realCount;
                realCount = value;
                OnPropertyChanged("RealCount", previewVlaue, realCount);
            }
        }

        private short workpieceSource;
        /// <summary>
        /// 工件来源
        /// </summary>
        public short WorkpieceSource
        {
            get
            {
                return workpieceSource;
            }
            set
            {
                short previewVlaue = workpieceSource;
                workpieceSource = value;
                OnPropertyChanged("WorkpieceSource", previewVlaue, workpieceSource);
            }
        }

        private short countSet;
        /// <summary>
        /// 测量次数设定
        /// </summary>
        public short CountSet
        {
            get
            {
                return countSet;
            }
            set
            {
                short previewVlaue = countSet;
                countSet = value;
                OnPropertyChanged("CountSet", previewVlaue, countSet);
            }
        }

        private string materialCode;
        /// <summary>
        /// 物料码
        /// </summary>
        public string MaterialCode
        {
            get
            {
                return materialCode;
            }
            set
            {
                string previewVlaue = materialCode;
                materialCode = value;
                OnPropertyChanged("MaterialCode", previewVlaue, materialCode);
            }
        }

        private double depth;
        /// <summary>
        /// 零件深度
        /// </summary>
        public double Depth
        {
            get
            {
                return depth;
            }
            set
            {
                double previewVlaue = depth;
                depth = value;
                OnPropertyChanged("Depth", previewVlaue, depth);
            }
        }

        private double hoLength;
        /// <summary>
        /// 零件长度
        /// </summary>
        public double HoLength
        {
            get
            {
                return depth;
            }
            set
            {
                double previewVlaue = hoLength;
                hoLength = value;
                OnPropertyChanged("HoLength", previewVlaue, hoLength);
            }
        }

        private bool valAct;
        /// <summary>
        /// 读取信号
        /// </summary>
        public bool ValAct
        {
            get
            {
                return valAct;
            }
            set
            {
                bool previewVlaue = valAct;
                valAct = value;
                OnPropertyChanged("ValAct", previewVlaue, valAct);
            }
        }
        #endregion
    }
}
